#!/usr/bin/env python3
"""
DSL语法修复脚本 - 第一阶段额外修复
处理剩余的语法错误：
1. 移除无效的规则键（sensitive, pattern）
2. 修复命令参数引用问题
"""

import os
import re
import yaml
import sys
from pathlib import Path

def load_yaml_file(file_path):
    """加载YAML文件"""
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            return yaml.safe_load(f)
    except Exception as e:
        print(f"❌ 无法加载文件 {file_path}: {e}")
        return None

def save_yaml_file(file_path, data):
    """保存YAML文件"""
    try:
        with open(file_path, 'w', encoding='utf-8') as f:
            yaml.dump(data, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
        return True
    except Exception as e:
        print(f"❌ 无法保存文件 {file_path}: {e}")
        return False

def remove_invalid_rules(attributes):
    """移除无效的规则键"""
    invalid_rules = ['sensitive', 'pattern']
    changes = []
    
    for attr_name, attr_def in attributes.items():
        if 'rules' in attr_def and isinstance(attr_def['rules'], list):
            original_rules = attr_def['rules'][:]
            new_rules = []
            
            for rule in original_rules:
                if isinstance(rule, dict):
                    # 移除无效的规则键
                    valid_rule = {}
                    for key, value in rule.items():
                        if key not in invalid_rules:
                            valid_rule[key] = value
                    if valid_rule:
                        new_rules.append(valid_rule)
                elif isinstance(rule, str) and rule not in invalid_rules:
                    new_rules.append(rule)
                elif isinstance(rule, str) and rule in invalid_rules:
                    changes.append(f"    🗑️  移除无效规则 '{rule}': {attr_name}")
            
            attr_def['rules'] = new_rules
    
    return changes

def fix_command_params(entity_name, entity_def):
    """修复命令参数引用问题"""
    changes = []
    
    if 'commands' not in entity_def:
        return changes
    
    # 获取实体的属性列表和identity字段
    attributes = set()
    identity_field = None
    
    if 'attributes' in entity_def:
        attributes = set(entity_def['attributes'].keys())
    
    if 'identity' in entity_def:
        identity_field = entity_def['identity']
        attributes.add(identity_field)
    
    # 定义常见的参数映射
    param_mappings = {
        'password': 'passwordHash',
        'usernameOrEmail': 'username',  # 或者可以映射到email
        'sessionId': 'id',  # 对于UserSession实体
        'token': 'emailVerificationToken',  # 或其他token字段
        'currentPassword': 'passwordHash',
        'newPassword': 'passwordHash',
        'permissionIds': 'id'  # 对于Permission实体
    }
    
    for cmd_name, cmd_def in entity_def['commands'].items():
        if 'params' not in cmd_def:
            continue
            
        new_params = []
        for param in cmd_def['params']:
            if param in attributes or param == identity_field:
                new_params.append(param)
            elif param in param_mappings and param_mappings[param] in attributes:
                # 映射到已存在的属性
                mapped_param = param_mappings[param]
                new_params.append(mapped_param)
                changes.append(f"    🔄 映射参数 '{param}' -> '{mapped_param}': {entity_name}.{cmd_name}")
            else:
                # 对于无法映射的参数，暂时保留但添加注释
                new_params.append(param)
                changes.append(f"    ⚠️  保留未映射参数 '{param}': {entity_name}.{cmd_name}")
        
        cmd_def['params'] = new_params
    
    return changes

def process_file(file_path):
    """处理单个YAML文件"""
    print(f"\n📝 处理文件: {os.path.basename(file_path)}")
    
    # 创建备份
    backup_path = f"{file_path}.backup-phase1-additional"
    try:
        with open(file_path, 'r', encoding='utf-8') as src, open(backup_path, 'w', encoding='utf-8') as dst:
            dst.write(src.read())
    except Exception as e:
        print(f"❌ 无法创建备份: {e}")
        return False
    
    # 加载YAML数据
    data = load_yaml_file(file_path)
    if not data:
        return False
    
    total_changes = []
    
    # 处理每个实体
    if 'entities' in data:
        for entity_name, entity_def in data['entities'].items():
            print(f"  🔧 修复实体: {entity_name}")
            entity_changes = []
            
            # 移除无效规则
            if 'attributes' in entity_def:
                rule_changes = remove_invalid_rules(entity_def['attributes'])
                entity_changes.extend(rule_changes)
            
            # 修复命令参数
            param_changes = fix_command_params(entity_name, entity_def)
            entity_changes.extend(param_changes)
            
            total_changes.extend(entity_changes)
            
            # 打印实体的修改
            for change in entity_changes:
                print(change)
    
    # 保存修改后的文件
    if save_yaml_file(file_path, data):
        print(f"✅ {os.path.basename(file_path)} 修复完成")
        return True
    else:
        # 恢复备份
        try:
            with open(backup_path, 'r', encoding='utf-8') as src, open(file_path, 'w', encoding='utf-8') as dst:
                dst.write(src.read())
        except:
            pass
        return False

def main():
    if len(sys.argv) != 2:
        print("用法: python3 fix-dsl-syntax-phase1-additional.py <models_directory>")
        sys.exit(1)
    
    models_dir = Path(sys.argv[1])
    if not models_dir.exists():
        print(f"❌ 目录不存在: {models_dir}")
        sys.exit(1)
    
    print("🚀 开始第一阶段额外DSL语法修复...")
    print("=" * 50)
    
    # 查找所有YAML文件（排除备份文件）
    yaml_files = []
    for file_path in models_dir.glob("*.yml"):
        if not file_path.name.endswith('.backup') and not file_path.name.endswith('.backup-phase1') and not file_path.name.endswith('.backup-phase1-additional'):
            yaml_files.append(file_path)
    
    if not yaml_files:
        print("❌ 未找到YAML文件")
        sys.exit(1)
    
    success_count = 0
    processed_files = []
    
    # 处理每个文件
    for file_path in sorted(yaml_files):
        if process_file(file_path):
            success_count += 1
            processed_files.append(file_path.name)
    
    # 输出总结
    print("\n" + "=" * 50)
    print("📊 第一阶段额外DSL语法修复完成")
    print("=" * 50)
    print(f"✅ 成功处理: {success_count} 个文件")
    for file_name in processed_files:
        print(f"   - {file_name}")
    
    print(f"\n🔧 主要修复内容:")
    print(f"   - 🗑️  移除无效验证规则(sensitive, pattern)")
    print(f"   - 🔄 修复命令参数引用问题")
    
    print(f"\n💾 备份文件已创建（.backup-phase1-additional后缀）")
    print(f"📝 建议运行语法检查: npx tsx src/cli/syntax-check.ts models")
    print(f"🔄 如需恢复: find models -name '*.backup-phase1-additional' -exec sh -c 'mv \"$1\" \"${{1%.backup-phase1-additional}}\"' _ {{}} \\;")

if __name__ == "__main__":
    main()